﻿using System;
using System.Collections.Generic;
using NHibernate.Criterion;
using SimpleServiceBus.Persistence.Domain.Management.Entities;
using SimpleServiceBus.Persistence.Domain.Management.Repositories;

namespace SimpleServiceBus.Persistence.NHibernate.Repositories
{
    public class EndpointPerformanceSummaryRepository : Repository<EndpointPerformanceSummary>, IEndpointPerformanceSummaryRepository
    {
        public IList<EndpointPerformanceSummary> FindByEndpoint(ManagedEndpoint endpoint, string metricName, DateTime? startTime, DateTime? endTime)
        {
            DateTime from = (startTime == null) ? DateTime.Now.AddHours(-24) : startTime.Value;
            DateTime to = (endTime == null) ? DateTime.Now : endTime.Value;

            return CreateCriteria(null)
                .CreateAlias("Metric", "metric")
                .Add(Expression.Eq("ManagedEndpoint", endpoint))
                .Add(Expression.Eq("metric.Name", metricName))
                .Add(Expression.Between("SamplePeriodEndTime", from.ToUniversalTime(), to.ToUniversalTime()))
                .List<EndpointPerformanceSummary>();
        }

        public IList<EndpointPerformanceSummary> FindByEndpoint(ManagedEndpoint endpoint, int? maxResults, DateTime? startTime, DateTime? endTime)
        {
            int topcount = (maxResults == null || maxResults.Value <= 0) ? 100 : maxResults.Value;
            DateTime from = (startTime == null) ? DateTime.Now.AddHours(-24) : startTime.Value;
            DateTime to = (endTime == null) ? DateTime.Now : endTime.Value;

            return FindTopN(topcount, "SamplePeriodEndTime", false, Expression.Eq("ManagedEndpoint", endpoint),
                            Expression.Between("SamplePeriodEndTime", from.ToUniversalTime(), to.ToUniversalTime()));
        }

        public IList<EndpointPerformanceSummary> GetSummariesForEndpoint(EndpointMetricType metric, ManagedEndpoint endpoint,DateTime startDate,DateTime endDate)
        {
            return FindAll(
                Expression.Eq("Metric", metric),
                Expression.Eq("ManagedEndpoint", endpoint),
                Expression.Between("SamplePeriodEndTime",startDate,endDate));
        }

        public string[] GetMetricTypesForEndpoint(ManagedEndpoint endpoint)
        {
            var results = CreateCriteria(null)
                .Add(Expression.Eq("ManagedEndpoint", endpoint))
                .CreateAlias("Metric", "metric")
                .SetProjection(Projections.Distinct(Projections.ProjectionList()
                                                        .Add(Projections.Alias(Projections.Property("metric.Name"),
                                                                               "Metric"))))
                .List();
            var metrics = new string[results.Count];
            results.CopyTo(metrics, 0);
            return metrics;
            
        }
    }
}
